/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.rbac.service.menu.impl;

import com.alibaba.fastjson2.JSONObject;
import com.je.common.base.DynaBean;
import com.je.common.base.entity.func.FuncInfo;
import com.je.common.base.entity.func.FuncQueryStrategy;
import com.je.common.base.mapper.query.Condition;
import com.je.common.base.mapper.query.NativeQuery;
import com.je.common.base.mapper.query.Query;
import com.je.common.base.mvc.BaseMethodArgument;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaResourceService;
import com.je.common.base.service.MetaService;
import com.je.common.base.service.QueryBuilderService;
import com.je.common.base.service.impl.PlatformServiceImpl;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.ibatis.extension.plugins.pagination.Page;
import com.je.rbac.service.menu.MenuBatchAddService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service("menuBatchAddService")
public class MenuBatchAddServiceImpl implements MenuBatchAddService {

    @Autowired
    private MetaService metaService;
    @Autowired
    private MetaResourceService metaResourceService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private QueryBuilderService queryBuilder;
    @Autowired
    private PlatformServiceImpl platformService;


    @Override
    public Page load(BaseMethodArgument param, HttpServletRequest request) {
        if (param.getLimit() == 0) {
            param.setLimit(-1);
        }

        //分页对象
        Page page = new Page<>(param.getPage(), param.getLimit());

        String funcCode = param.getFuncCode();

        //构建查询条件
        ConditionsWrapper wrapper = buildWrapper(param, request);
        List<Map<String, Object>> list = metaService.load(funcCode, page, wrapper);
        page.setRecords(list);
        return page;
    }


    public ConditionsWrapper buildWrapper(BaseMethodArgument param, HttpServletRequest request) {
        //功能code，表code
        String funcCode = param.getFuncCode();
        String tableCode = param.getTableCode();

        //获取查询条件
        Query query = param.buildQuery();
        List<Condition> conditionList = query.getCustom();
        for (Condition condition : conditionList) {
            List valueArray = (List) condition.getValue();
            for (Object o : valueArray) {
                if (o instanceof JSONObject) {
                    JSONObject menuNotIdJson = (JSONObject) o;
                    if (menuNotIdJson.get("code").equals("JE_CORE_MENU_ID") && menuNotIdJson.get("type").equals("notIn")) {
                        if (menuNotIdJson.get("value") instanceof ArrayList) {
                            List values = (List) menuNotIdJson.get("value");
                            List<Object> putValue = new ArrayList<>();
                            for (Object v : values) {
                                if (v instanceof String && v.toString().toUpperCase().startsWith("SELECT RELATION_MENUMODULE_ID FROM JE_RBAC_HEADMENU_RELATION WHERE JE_RBAC_HEADMENU_ID=")) {
                                    List<Map<String, Object>> menuIds = metaService.selectSql(v.toString());
                                    for (Map<String, Object> map : menuIds) {
                                        putValue.add(map.get("RELATION_MENUMODULE_ID"));
                                    }
                                }
                            }
                            menuNotIdJson.put("value", putValue);
                        }
                    }
                }
            }
        }
        query.setFuncId(param.getFuncId());
        query.setFuncCode(funcCode);

        //设置是否覆盖功能whereSql
        query.setOverrideFuncWhere("1".equals(platformService.getStringParameter(request, "coverJquery")));
        query.setSyProductId(platformService.getStringParameter(request, "SY_PRODUCT_ID"));

        //功能相关配置
        if (StringUtils.isNotBlank(funcCode)) {
            //获取功能配置
            FuncInfo funcInfo = commonService.functionConfig(funcCode);
            query.setFuncId(funcInfo.getFuncId());
            query.setFuncPkCode(funcInfo.getPkCode());
            query.setFuncWhereSql(funcInfo.getWhereSql());
            query.setFuncOrderSql(funcInfo.getOrderSql());

            //获取查询策略
            if (StringUtils.isNotBlank(query.getStrategyId())) {
                FuncQueryStrategy strategy = null;
                //查找缓存中的查询策略
                if (funcInfo.getStrategies() != null) {
                    List<FuncQueryStrategy> strategiesFilter = funcInfo.getStrategies().stream()
                            .filter(p -> query.getStrategyId().equals(p.getId())).collect(Collectors.toList());
                    if (!strategiesFilter.isEmpty()) {
                        strategy = strategiesFilter.get(0);
                    }
                }
                //数据库查找查询策略
                if (strategy == null) {
                    //7.封装查询策略
                    DynaBean queryStrategy = metaResourceService.selectOneByNativeQuery("JE_CORE_QUERYSTRATEGY", NativeQuery.build().eq("JE_CORE_QUERYSTRATEGY_ID", query.getStrategyId()));
                    if (queryStrategy != null) {
                        strategy = new FuncQueryStrategy(queryStrategy.getStr("JE_CORE_QUERYSTRATEGY_ID"), queryStrategy.getStr("QUERYSTRATEGY_SQL"), queryStrategy.getStr("QUERYSTRATEGY_FGGNSQL"));
                    }
                }
                query.setStrategyBean(strategy);
            }
        }

        //设置条件
        ConditionsWrapper wrapper = queryBuilder.buildWrapper(query);


        wrapper.function(funcCode).table(tableCode).selectColumns(param.getQueryColumns());

        return wrapper;
    }

}
